//
// Created by Jisam on 07/10/2024 23:29.
// Solution of  P1074 靶形数独
// 2024-10-08 00:11:31 AC 100

// 包含标准模板库头文件
#include <bits/stdc++.h>

// 定义宏来简化代码
#define  int long long  // 将int类型定义为long long，用于支持大数
#define  endl "\n"       // 定义换行符
#define  pb push_back    // 定义向vector中添加元素的简写
#define  all(x) (x).begin(),(x).end()  // 定义迭代器的简写

// 使用标准命名空间std
using namespace std;

// 定义一个内联函数read()用于读取整数
inline int read() {
    int x = 0, f = 1;  // x用于存储读取的数值，f用于存储符号
    char ch = getchar();  // 读取一个字符
    while (ch < '0' || ch > '9') {  // 当字符不是数字时
        if (ch == '-')  // 如果字符是负号
            f = -1;  // 改变符号
        ch = getchar();  // 继续读取下一个字符
    }
    while (ch >= '0' && ch <= '9') {  // 当字符是数字时
        x = (x << 1) + (x << 3) + (ch ^ 48);  // 将数字字符转换为整数并累加
        ch = getchar();  // 继续读取下一个字符
    }
    return x * f;  // 返回最终的数值，考虑正负号
}

// 定义常量和数组
const int MAXN = 12;  // 最大行数
const int score[10][10] =  // 定义分数数组，用于计算靶形数独的分数
        {{0, 0, 0, 0, 0, 0,  0, 0, 0, 0},
         {0, 6, 6, 6, 6, 6,  6, 6, 6, 6},
         {0, 6, 7, 7, 7, 7,  7, 7, 7, 6},
         {0, 6, 7, 8, 8, 8,  8, 8, 7, 6},
         {0, 6, 7, 8, 9, 9,  9, 8, 7, 6},
         {0, 6, 7, 8, 9, 10, 9, 8, 7, 6},
         {0, 6, 7, 8, 9, 9,  9, 8, 7, 6},
         {0, 6, 7, 8, 8, 8,  8, 8, 7, 6},
         {0, 6, 7, 7, 7, 7,  7, 7, 7, 6},
         {0, 6, 6, 6, 6, 6,  6, 6, 6, 6}};
int row[MAXN][MAXN], col[MAXN][MAXN], area[MAXN][MAXN], sdk[MAXN][MAXN];  // 定义行、列、区域和解决方案数组
int row_cnt[MAXN], col_cnt[MAXN], cnt, ans = -1;  // 定义行计数、列计数、计数器和答案变量
int n = 9;  // 定义数独的大小

// 定义一个内联函数id()用于计算区域编号
inline int id(int i, int j) {
    return (i - 1) / 3 * 3 + 1 + (j - 1) / 3;  // 计算并返回区域编号
}

// 定义一个内联函数calc()用于计算得分
inline int calc() {
    int tmp = 0;  // 定义临时变量用于累加分数
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            tmp += score[i][j] * sdk[i][j];  // 根据分数数组和解决方案数组计算总分
        }
    }
    return tmp;  // 返回计算的总分
}

// 定义dfs函数用于深度优先搜索
void dfs(int r, int c, int count) {
    if (count == 81) {  // 如果已经填充了81个数字
        ans = max(ans, calc());  // 更新答案
        return;
    }
    for (int k = 1; k <= n; k++) {  // 尝试每个可能的数字
        if (row[r][k] || col[c][k] || area[id(r, c)][k]) {
            continue;  // 如果数字已经在行、列或区域中，则跳过
        }
        row[r][k] = 1;  // 标记数字k在行r中
        col[c][k] = 1;  // 标记数字k在列c中
        area[id(r, c)][k] = 1;  // 标记数字k在区域中
        row_cnt[r]++;  // 增加行r的计数
        col_cnt[c]++;  // 增加列c的计数
        sdk[r][c] = k;  // 在解决方案数组中设置数字k
        int tr = -1, nr = 0, tc = -1, nc = 0;  // 定义行和列的临时变量
        for (int i = 1; i <= n; i++) {
            if (row_cnt[i] > tr && row_cnt[i] < n) {  // 找到下一个行的最小计数
                tr = row_cnt[i];
                nr = i;
            }
        }
        for (int j = 1; j <= n; j++) {
            if (col_cnt[j] > tc && !sdk[nr][j]) {  // 找到下一个列的最小计数
                tc = col_cnt[j];
                nc = j;
            }
        }
        dfs(nr, nc, count + 1);  // 递归调用dfs函数
        row[r][k] = 0;  // 回溯
        col[c][k] = 0;
        area[id(r, c)][k] = 0;
        row_cnt[r]--;
        col_cnt[c]--;
        sdk[r][c] = 0;
    }
}

// 定义主函数
signed main() {
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= 9; j++) {
            sdk[i][j] = read();  // 读取解决方案数组的值
            if (sdk[i][j]) {
                row[i][sdk[i][j]] = 1;  // 如果有值，则标记行
                col[j][sdk[i][j]] = 1;  // 标记列
                area[id(i, j)][sdk[i][j]] = 1;  // 标记区域
                row_cnt[i]++, col_cnt[j]++;  // 更新行和列的计数
                cnt++;  // 更新计数器
            }
        }
    }
    int tr = -1, tc = -1, r, c;  // 定义行和列的临时变量
    for (int i = 1; i <= n; i++) {
        if (row_cnt[i] > tr && row_cnt[i] < 9) {  // 找到行的最小计数
            tr = row_cnt[i];
            r = i;
        }
    }
    for (int j = 1; j <= n; j++) {
        if (col_cnt[j] > tc && (!sdk[r][j])) {  // 找到列的最小计数
            tc = col_cnt[j];
            c = j;
        }
    }
    dfs(r, c, cnt);  // 调用dfs函数
    cout << ans << endl;  // 输出答案
    return 0;
}